// 图层控制
import * as Cesium from 'cesium'

class Layer {
  constructor () {}

  // 初始化
  init (viewer) {
    this._viewer = viewer
    this._imageryLayers = []
    this._vectorLayers = []
    this._terrainLayer = null
    this._tiltModelLayers = []
  }

  // 加载图像图层
  loadImageLayer (data) {
    return this.loadLayer(data)
  }

  // 加载图层
  loadLayer (data) {
    this.resolveConfig(data)
    // 图像图层
    let layer = this.getImageLayer(data.id)
    if (layer) {
      return this.renderImageLayer(data.id, data.isShow)
    }
    // 矢量图层
    if (/geojson|kml/i.test(data.type)) {
      layer = this.getVectorLayer(data.id)
    }
    if (layer) {
      return this.renderVectorLayer(data.id, data.isShow)
    }

    // 新图层
    if (/wmts/i.test(data.type)) {
      return this.loadWmtsLayer(data)
    } else if (/wms/i.test(data.type)) {
      return this.loadWmsLayer(data)
    } else if (/ut/i.test(data.type)) {
      return this.loadUtLayer(data)
    } else if (/basic/i.test(data.type)) {
      return this.loadBasicLayer(data)
    } else if (/geojson/i.test(data.type)) {
      return this.loadGeoJsonLayer(data)
    } else if (/kml/i.test(data.type)) {
      return this.loadKMLLayer(data)
    }
  }

  // 加载wmts图层
  loadWmtsLayer (data) {
    let isC = data.tileMatrixSetID === 'c' // 是否经纬度投影
    var wmts = new Cesium.WebMapTileServiceImageryProvider({
      url: new Cesium.Resource({
        url: data.url
      }),
      credit: data.label,
      layer: data.layer || 'wmts',
      style: data.style || 'default',
      format: data.format || 'image/png',
      transparent: true, // 确保透明度
      tileMatrixSetID: data.tileMatrixSetID || 'EPSG:4326', // 坐标系
      subdomains: data.subdomains, // 服务域名
      tilingScheme: isC ? new Cesium.GeographicTilingScheme() : undefined,
      tileMatrixLabels: isC ? [
        '1', '2', '3', '4',
        '5', '6', '7', '8', '9', '10', '11',
        '12', '13', '14', '15', '16', '17', '18'
      ] : undefined,
      maximumLevel: 18 // 设置最高显示层级
    })
    var layer = this._viewer.imageryLayers.addImageryProvider(wmts)
    layer.zindex = data.zindex
    this._imageryLayers.push({ id: data.id, layer: layer })
    this.renderImageLayer(data.id, data.isShow)
    return layer
  }

  // 加载wms图层
  loadWmsLayer (data) {
    let map = new Cesium.WebMapServiceImageryProvider({
      url: new Cesium.Resource({
        url: data.url
      }),
      credit: data.label,
      layers: data.layers || data.layer || 'wms', // 图层名
      format: data.format || 'image/png',
      parameters: {
        // styles: "ludibianjiehei", // 使用其他样式
        service: 'WMS',
        format: data.format || 'image/png',
        transparent: true, // 是否透明
        // CQL_FILTER:`city_code=${city_code}`
        // geoserver服务，可通过cql进行特征筛选(多个数据：city_code in ('地瓜','花生'))
      }
    })
    map.customName = 'tianditu3' // 自己定义各种属性
    const layer = this._viewer.imageryLayers.addImageryProvider(map) // 添加图层
    layer.zindex = data.zindex
    this._imageryLayers.push({ id: data.id, layer: layer })
    this.renderImageLayer(data.id, data.isShow)
    return layer
  }

  // 地图模板图层
  loadUtLayer (data) {
    var ut = new Cesium.UrlTemplateImageryProvider({
      url: new Cesium.Resource({
        url: data.url
      }),
      credit: data.label || 'amap',
      layer: data.layer || 'ut',
      style: data.style || 'default',
      format: data.format || 'image/png',
      transparent: true, // 设置图层透明
      tileMatrixSetID: data.tileMatrixSetID || 'EPSG:4326', // 坐标系
      subdomains: data.subdomains, // 服务域名
      maximumLevel: 18 // 设置最高显示层级
    })
    var layer = this._viewer.imageryLayers.addImageryProvider(ut)
    layer.zindex = data.zindex
    this._imageryLayers.push({ id: data.id, layer: layer })
    this.renderImageLayer(data.id, data.isShow);
    return layer
  }

  // 基础图层
  loadBasicLayer (data) {
    let map = null
    // 分经纬度与墨卡托
    let params = data.projective === 'web_mercator' ? {
      tilingScheme: new Cesium.WebMercatorTilingScheme
    } : {
      tilingScheme: new Cesium.GeographicTilingScheme
    }
    if (/TileCoordinatesImageryProvider/i.test(data.url)) {
      map = new Cesium.TileCoordinatesImageryProvider(params)
    } else if (/GridImageryProvider/i.test(data.url)) {
      map = new Cesium.GridImageryProvider(params)
    }
    if (!map) {
      return true
    }
    const layer = this._viewer.imageryLayers.addImageryProvider(map) // 添加图层
    layer.zindex = data.zindex
    this._imageryLayers.push({ id: data.id, layer: layer })
    this.renderImageLayer(data.id, data.isShow)
    return layer
  }

  // KML图层
  loadKMLLayer (data) {
    // 加载kml数据
    return Cesium.KmlDataSource.load(data.url).then((dataSource) => {
      this._viewer.dataSources.add(dataSource)
      this._vectorLayers.push({ id: data.id, layer: dataSource })
      this.renderVectorLayer(data.id, data.isShow)
      return dataSource
    })
  }

  // GeoJson图层
  loadGeoJsonLayer (data) {
    var color = Cesium.Color.fromRandom(), fill
    if (data.color) {
      color = Cesium.Color.fromCssColorString(data.color)
    }
    if (data.fill) {
      fill = Cesium.Color.fromCssColorString(data.fill).withAlpha(0.3)
    }
    // 加载GeoJSON数据
    return Cesium.GeoJsonDataSource.load(data.url, {
      stroke: color,
      strokeWidth: data.strokeWidth || 1,
      fill: fill,
      markerSymbol: data.markerSymbol
    }).then((dataSource) => {
      this._viewer.dataSources.add(dataSource)
      this._vectorLayers.push({ id: data.id, layer: dataSource })
      this.renderVectorLayer(data.id, data.isShow)
      return dataSource
    })
  }

  // 获取所有图像图层
  getImageLayers () {
    return this._imageryLayers
  }

  // 获取图像图层
  getImageLayer (id) {
    for (var data of this._imageryLayers) {
      if (data.id === id) {
        return data.layer
      }
    }
  }

  // 渲染多个图层
  renderImageLayers (list, { isHideLayer, allLayers } = {}) {
    // 隐藏未指定的图层
    if (isHideLayer === true) {
      allLayers = allLayers || this._imageryLayers
      for (var data of allLayers) {
        if (!list.includes(data.id)) {
          this.renderImageLayer(data.id, false)
        }
      }
    }
    // 渲染指定图层
    list.forEach(item => {
      this.loadImageLayer(item)
    })
  }

  // 清除图像图层
  clearImageLayers (id) {
    let ids = Array.isArray(id) ? id : [id]
    this._imageryLayers = this._imageryLayers.filter(item => {
      let node = ids.find(sec => sec === undefined || item.id === sec)
      if (node) {
        this._viewer.imageryLayers.remove(item.layer, true) // 删除图层
        return false
      }
      return true
    })
  }

  // 渲染单个图层
  renderImageLayer (id, isShow) {
    var layer = this.getImageLayer(id)
    if (layer) {
      layer.show = isShow
    }
  }

  // 渲染矢量图层
  renderVectorLayer (id, isShow) {
    var layer = this.getVectorLayer(id)
    if (layer) {
      layer.show = isShow
    }
  }

  // 获取矢量图层
  getVectorLayer (id) {
    for (var data of this._vectorLayers) {
      if (data.id === id) {
        return data.layer
      }
    }
  }

  // 清除矢量图层
  clearVectorLayers (id) {
    let ids = Array.isArray(id) ? id : [id]
    this._vectorLayers = this._vectorLayers.filter(item => {
      let node = ids.find(sec => sec === undefined || item.id === sec)
      if (node) {
        this._viewer.dataSources.remove(item.layer, true) // 删除图层
        return false
      }
      return true
    })
  }

  // 清除图层
  clearLayers (id) {
    this.clearImageLayers(id)
    this.clearVectorLayers(id)
  }

  // 按层级排序
  sortLayers (layers) {
    layers = layers || this._viewer
    ._layers
    layers = layers.sort((a, b) => {
      return a.zindex > b.zindex ? -1 : a.zindex < b.zindex ? 1 : 0
    }).map(item => item)
    layers.forEach((item) => {
      // if (!i && item._isBaseLayer) {
      //   return
      // }
      this._viewer.imageryLayers.lowerToBottom(item)
    })
  }

  // 解析配置
  resolveConfig (data) {
    if (!data) {
      return data
    }
    // token
    let tk = Array.isArray(data.tk) ? data.tk : [data.tk]
    tk = tk[Math.floor(Math.random() * (tk.length))]
    if (tk && data.url) {
      data.url = String(data.url).replace('{tk}', tk)
      // file协议转为http
      if (/file/.test(location.protocol) && /^\/\//.test(data.url)) {
        data.url = 'http:' + data.url
      }
    }
  }
}

const layer = new Layer()

export default layer

export {
  Layer
}